package com.guxingke.gsb.service;

import com.github.jknack.handlebars.Handlebars;
import com.guxingke.gsb.config.Config;
import com.guxingke.gsb.config.Constant;
import com.guxingke.gsb.io.FileAccess;
import com.guxingke.gsb.model.IndexModel;
import com.guxingke.gsb.model.Meta;
import com.guxingke.gsb.model.Page;
import com.guxingke.gsb.model.Post;
import com.guxingke.gsb.parse.Parser;
import com.guxingke.gsb.render.HandlebarsRender;
import com.guxingke.gsb.repo.GsbRepo;
import com.guxingke.gsb.server.FileServer;
import com.guxingke.gsb.util.PathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 孤星可 on 2015/11/25.
 *
 * @author guxingke
 * @since 2015/11/25
 */
public class GsbService implements IGsbService {
    private static final Logger logger = LoggerFactory.getLogger(GsbService.class);

    private FileAccess fileAccess;
    private FileServer fileServer;

    public GsbService() {
        fileAccess = new FileAccess();
    }

    @Override
    public boolean init(String sitePath) {
        Path path;
        try {
            path = Paths.get(sitePath);
        } catch (InvalidPathException e) {
            logger.error("init site failed", e);
            return false;
        }

        //1.创建global.toml
        boolean write = writeGlobalConfig(path);
        if (!write) {
            logger.error("init site failed#write global.toml failed");
            return false;
        }

        //2.生成脚手架
        boolean generateStatus = generateEmptySite(path);
        if (!generateStatus) {
            logger.error("init site failed#copy scaffold failed");
            return false;
        }
        return true;
    }

    @Override
    public boolean publish(String sitePath) {
        HandlebarsRender render = HandlebarsRender.getInstance(
                Config.getThemeConfigPath(), ".html"
        );

        //1.解析content目录下的md文件，md->Parseable
        Path contentPath = Paths.get(sitePath, Constant.CONTENT_DIRECTORY);
        List<Path> paths = null;
        try {
            paths = fileAccess.parsePathFromDirectory(contentPath, "md", false);
        } catch (IOException e) {
            logger.error("parse content failed", e);
        }
        Parser.parse(paths);

        //2.生成静态页
        //2.1 post
        List<Post> posts = GsbRepo.getPosts();
        boolean renderPosts = render.renderPosts(posts);
        if (!renderPosts) {
            logger.error("render posts failed");
        }

        //2.2 page
        List<Page> pages = GsbRepo.getPages();
        boolean renderPages = render.renderPages(pages);
        if (!renderPages) {
            logger.error("render pages failed");
        }

        //2.3 others TODO
        List<IndexModel> indexs = GsbRepo.getIndexs(2);
        boolean renderIndex = render.renderIndex(indexs);
        if (!renderIndex) {
            logger.error("render index failed");
        }

        //3.copy assets
        boolean copy = fileAccess.copyDirectory(
                Paths.get(Config.getThemeConfigPath(), "assets"),
                Paths.get(sitePath, Constant.OUTPUT_DIRECTORY, "assets"));
        if (!copy) {
            logger.error("copy asset failed");
        }
        return true;
    }

    @Override
    public boolean deploy(String sitePath) {
        return false;
    }

    @Override
    public void previewOnLocal(String outputPath,Integer port) {
        fileServer = new FileServer(port);
        fileServer.startPreview(outputPath);
    }

    @Override
    public void previewStop(Integer port) {
        String url = "http://localhost:"+ port+"/shutdown?token=stop";
        FileServer.openBrowser(url);
    }


    @Override
    public boolean clean(String sitePath, boolean removeGitDir) {
        Path path = Paths.get(sitePath, Constant.OUTPUT_DIRECTORY);
        return fileAccess.cleanDirectory(path, removeGitDir);
    }

    private boolean generateEmptySite(Path sitePath) {
        String classRootPath = PathUtil.getClassRootPath();
        Path source = Paths.get(classRootPath, Constant.SCAFFOLD_NAME);
        return fileAccess.copyDirectory(source, sitePath);
    }

    private boolean writeGlobalConfig(Path path) {
        String classRootPath = PathUtil.getClassRootPath();
        Path classPath = Paths.get(classRootPath);
        String sitePath = path.toString();
        StringBuffer content = new StringBuffer();
        String spit = PathUtil.getSystemPathSpit();
        content.append("sitePath = [");
        for (String s : sitePath.split(spit)) {
            content.append("\"" + s + "\",");
        }
        content.deleteCharAt(content.length() - 1);
        content.append("]");
        content.append(PathUtil.LINE_SEPARATOR);

        return fileAccess.write(classPath, Constant.GLOBAL_CONFIG_FILENAME, content.toString());
    }
}
